package mdt.figure;

import org.tigris.gef.presentation.Fig;
import org.tigris.gef.presentation.FigDiamond;
import org.tigris.gef.presentation.FigRect;
import mdt.model.IDiamondChoice;
import mdt.model.INodeModel;

import java.awt.*;

/**
 * Created by xiaobyu on 7/15/2016.
 */
public class FigDiamondChoice extends FigNodeEditable{

    private FigDiamond diamond;
    private FigRect portWest, portEast, portSouth, portNorth;
    private static final int PORT_SIZE = 16;


    public static final long serialVersionUID = 1l;

    public FigDiamondChoice(IDiamondChoice owner, FigDiamond diamond) {
        super(owner, TextType.MULTI_LINE);

        this.diamond = diamond;

        Rectangle diamondBounds = diamond.getBounds();
        Dimension textMinSize = figText.getMinimumSize();
        diamondBounds.width = Math.max(diamondBounds.width, textMinSize.width * 2);
        diamondBounds.height = Math.max(diamondBounds.height, textMinSize.height * 2);
        diamond.setBounds(diamondBounds);

        figText.setBounds(diamondBounds.x + diamondBounds.width / 4, diamondBounds.y + diamondBounds.height / 4,
                diamondBounds.width / 2, diamondBounds.height / 2);
        removeFig(figText);
        addFig(diamond);
        addFig(figText);

        portWest = createAndBindPort(owner, IDiamondChoice.WEST, diamondBounds.x - PORT_SIZE / 2, diamondBounds.y + diamondBounds.height / 2 - PORT_SIZE / 2);

        portEast = createAndBindPort(owner, IDiamondChoice.EAST, diamondBounds.x + diamondBounds.width - PORT_SIZE / 2, diamondBounds.y + diamondBounds.height / 2- PORT_SIZE / 2);

        portNorth = createAndBindPort(owner, IDiamondChoice.NORTH, diamondBounds.x + diamondBounds.width / 2- PORT_SIZE / 2, diamondBounds.y - PORT_SIZE / 2);

        portSouth = createAndBindPort(owner, IDiamondChoice.SOUTH, diamondBounds.x + diamondBounds.width / 2- PORT_SIZE / 2 , diamondBounds.y + diamondBounds.height - PORT_SIZE / 2);
        fixPortStyle();
        setShadowSize(1);
        setOwner(owner);
    }

    private FigRectPort createAndBindPort(IDiamondChoice owner, int portLocation, int x, int y) {
        FigRectPort fig = new FigRectPort(portLocation, x, y, PORT_SIZE, PORT_SIZE);
        fig.setVisible(true);
        addFig(fig);
        bindPort(owner.connectorAt(portLocation), fig);
        return fig;
    }

    protected void initTextFig(INodeModel model) {
        super.initTextFig(model);
        figText.setTopMargin(2);
        figText.setBotMargin(2);
        figText.setLeftMargin(2);
        figText.setRightMargin(2);
        fixFigTextStyle();
    }

    private void fixFigTextStyle() {
        figText.setFilled(false);
        figText.setLineWidth(0);
    }

    private void fixPortStyle() {
        for (Fig fig : new Fig[] {portWest, portEast, portNorth, portSouth}) {
            fig.setFilled(false);
            fig.setLineWidth(0);
        }
    }

    public void setBoundsImpl(int x, int y, int width, int height) {
        Dimension minSize = getMinimumSize();
        width = Math.max(width, minSize.width);
        height = Math.max(height, minSize.height);
        diamond.setBounds(x + PORT_SIZE / 2, y + PORT_SIZE / 2, width - PORT_SIZE, height - PORT_SIZE);
        portWest.setBounds(x, y + height / 2 - PORT_SIZE / 2, PORT_SIZE, PORT_SIZE);
        portEast.setBounds(x + width - PORT_SIZE, y + height / 2- PORT_SIZE / 2, PORT_SIZE, PORT_SIZE);
        portNorth.setBounds(x + width / 2- PORT_SIZE / 2, y, PORT_SIZE, PORT_SIZE);
        portSouth.setBounds(x + width / 2- PORT_SIZE / 2, y + height - PORT_SIZE, PORT_SIZE, PORT_SIZE);
        super.setBoundsImpl(x, y, width, height);
    }

    protected void setTextFigBounds(int x, int y, int w, int h) {
        figText.setBounds(x + w / 4 + PORT_SIZE / 2, y + h / 4 + PORT_SIZE / 2, (w - PORT_SIZE) / 2 , (h - PORT_SIZE) / 2);
    }

    public Dimension getMinimumSize() {
        Dimension d = figText.getMinimumSize();
        return new Dimension(d.width * 2 + PORT_SIZE, d.height * 2 + PORT_SIZE);
    }

    public void setLineWidth(int lineWidth) {
        super.setLineWidth(lineWidth);
        fixFigTextStyle();
        fixPortStyle();
    }

    public void setFilled(boolean filled) {
        super.setFilled(filled);
        fixFigTextStyle();
        fixPortStyle();
    }

    private class FigRectPort extends FigRect {

        final int portLocation;
        public FigRectPort(int portLocation, int x, int y, int w, int h) {
            super(x, y, w, h);
            this.portLocation = portLocation;
        }

        public Point getClosestPoint(Point anotherPt) {
            return new Point(_x + _w / 2, _y + _h / 2);
        }
    }
}
